#include <iostream>
#include <thread>

using namespace  std;

void myprint()
{
    cout<<"我的线程开始执行..."<<endl;
    for(int i = 0;i<10;++i)
        cout<<i<<endl;
    cout<<"我的线程运行结束"<<endl;
}

class  TA
{
public:
    int &m_i;
    TA(int &t):m_i(t){} //如果传入的不是引用就不会出现这个问题，也就是主线程的局部变量的引用在子线程的调用
    TA(const TA &obj):m_i(obj.m_i)
    {//这个引用的初始化不能在函数体内进行初始化，用参数列表进行初始化
        cout<<"拷贝构造函数被调用"<<endl;
    }
    ~TA()
    {
        cout<<"析构函数被调用"<<endl;
    }

    void operator()(){ //伪函数
        cout<<"我是类对象"<<endl;
        cout<<m_i<<endl;
        cout<<m_i<<endl;
        cout<<m_i<<endl;
        cout<<m_i<<endl;
        }
};

int main() {
    //1.并发：两个或者更多的（独立的活动）同时进行；
    //一个程序同时执行多个独立的任务

    //2.可执行程序：磁盘上面的一个文件，是一个静态的概念，占的是磁盘空间

    //3，进程：一个程序运行起来之后，就会产生一个进程，这个是一个动态的概念，它占系统资源，包括CPU 内存等

    //4。线程：当一个进程运行起来之后，就会有一个主线程，这个主线程也是唯一的。
    //这个主线程会默默随着进程启动起来（进程退化为了主线程）
    //进程和主线程的生命周期保持一致
    //线程：用来执行代码的；会走一条代码的执行道路

    //除了主线程，我们可以自己创建子线程，这些子线程走其他的代码通道
    //每创建一个新的线程，我就可以在同一个时刻做其他的事情（执行不同的代码通路）

    //线程不是越多越好，每一个线程都有属于自己的堆栈空间，线程之间的切换需要保存中间的状态，耗费程序运行的时间



        //二、实现并发的手段

        //a.多个进程实现并发
        //b.单个进程里面多个线程实现并发，手动代码创建除了主线程之外的线程

        //三、多进程并发
        //多个进程的创建和初始化
        //多个进程之间的通信：管道，文件，消息队列，共享内存，mmap 内存映射
        //不在同一个设备，可以使用socket通信

        //四、单个进程中创建了多个线程（线程是轻量级的进程，每个线程都有自己的独立路径）
        //所有的线程是共享地址空间的，共享内存的（全局变量，全局指针，全局引用）都可以在线程里面传递
        //共享资源带来了访问一致性的问题，线程直接的同步

        //优先考虑多线程技术

        //五、程序开始运行，生成一个进程，所属的主线程开始运行
        //主线程从main函数开始执行，到return 主线程也执行完毕

        //自己创建的线程也需要从一个线程开始执行，称为初始函数，这个函数执行完毕，代表这个线程执行完毕

        //线程执行完毕的标志是：主线程执行完毕；如果子线程还没有执行完毕，这些子线程会被操作系统强行停止 。
        //所以，就得让子线程一直保持运行，不能让主线程先退出
        //这条规则有例外，后面会讲解


        //这个程序执行是有两条平行线在运行；主线程被阻塞了，子线程也不受影响

        //thread是标准库的类


        //thread mythread(myprint); //myprint 可调用对象；创建了线程；线程的起点是myprint
        //cout<<"111"<<endl;
        //mythread.join(); //说白了就是阻塞主线程，让主线程等到子线程执行完毕，回收子线程资源

        //detach：主线程可以先跑，留下子线程运行，子线程也不会退出
        //一旦detach之后，主线程与子线程的对象就失去了关联，这个线程就运行在后台了（守护线程），由C++运行时库进行了接管

        //joinable ：判断是否join 和 detach过，返回true ，代表可以join或者true
//        mythread.join();
//        if(mythread.joinable()) //不能join和detach两次
//        {
//            cout<<"joinable true"<<endl;
//        }
//        else{
//            cout<<"joinable false"<<endl;
//        }

//
//        int m = 8;
//        TA ta(m); //这个m是在主线程里面的，当后面用detach，这个m在主线程退出后就会析构，而子线程内部还在使用这个m的引用就会出现问题
//        thread myjob(ta); //可调用的类对象，这个对象属于主线程，有存在析构了无法使用子线程的问题吗？
//        //这个线程是被复制到子线程里面去了， 主线程的对象析构了，不影响子线程的使用
//
//        myjob.join();
    auto mylambomthread=[]{
        cout<<"线程开始执行..."<<endl;
        cout<<"线程执行结束"<<endl;

    };

        thread mythread(mylambomthread);
        mythread.join() ;


        cout<<"I love china!"<<endl;



    return 0;
}
